package com.qing.common.util

import android.util.Log

object Debug {

    const val INDEX_FILE_NAME = 0
    const val INDEX_CLASS_NAME = 1
    const val INDEX_METHOD_NAME = 2
    const val INDEX_LINE_NUMBER = 3

    private const val BASE_STACK_TRACE_INDEX = 4

    fun getCallersToString(depth: Int): String {
        val trace = Thread.currentThread().stackTrace
        val builder = StringBuilder()
        for ((index, _) in trace.withIndex()) {
            builder.append(getCaller(trace, index))
                .append(" ")
        }
        builder.setLength(builder.length - 1)
        return builder.toString()
    }

    fun getCaller(): String {
        return getCaller(Thread.currentThread().stackTrace, 0)
    }

    /**
     * 获取当前函数的调用栈, [depth] 深度, 以调用本身开始
     */
    fun getCallers(throwable: Throwable? = null, depth: Int = 0): Array<String> {
        val stackTrace = throwable?.stackTrace ?: Thread.currentThread().stackTrace
        if (stackTrace.isEmpty()) {
            return emptyArray() // 或者根据需求抛出异常，但原函数可能返回空数组？
        }
        val baseIndex = BASE_STACK_TRACE_INDEX
        val adjustedDepth = depth.coerceAtLeast(0)
        val index = baseIndex + adjustedDepth
        val validIndex = if (index < stackTrace.size) index else stackTrace.lastIndex
        val caller = stackTrace[validIndex]
        Log.d("LogUtil", "getCallers: ", Throwable())
        return arrayOf(
            caller.fileName ?: "",
            caller.className,
            caller.methodName,
            caller.lineNumber.toString()
        )
    }

    private fun getCaller(trace: Array<StackTraceElement>, depth: Int): String {
        if (depth + 4 == trace.size) {
            return "<bottom of call stack>"
        }
        val caller: StackTraceElement = trace[4 + depth]
        return caller.className + "#" + caller.methodName + ":" + caller.lineNumber
    }
}